<template>
  <!-- 时间范围选择器组件 -->
  <div class="time-range-picker">
    <!-- 开始时间选择器 -->
    <el-time-picker
      v-model="startTimeValue"
      format="HH:mm"
      placeholder="开始时间"
      @change="handleStartTimeChange"
      class="time-input"
      :step="1800"
      :arrow-control="true"
      :disabled-minutes="disabledNonHalfHourMinutes"
    />
    <!-- 时间分隔符 -->
    <span class="time-separator">至</span>
    <!-- 结束时间选择器 -->
    <el-time-picker
      v-model="endTimeValue"
      format="HH:mm"
      placeholder="结束时间"
      :disabled="!startTimeValue"
      :disabledHours="() => disabledHours(startTimeValue)"
      :disabledMinutes="disabledEndTimeMinutes"
      class="time-input"
      :step="1800"
      :arrow-control="true"
    />
  </div>
</template>

<script>
/**
 * 时间范围选择器组件
 * 提供时间范围的选择功能，支持半小时为单位的精确选择
 * 自动处理开始时间和结束时间的逻辑关系
 */
export default {
  name: 'TimeRangePicker',
  props: {
    /**
     * 开始时间，Date类型或null
     */
    startTime: {
      type: [Date, null],
      default: null
    },
    /**
     * 结束时间，Date类型或null
     */
    endTime: {
      type: [Date, null],
      default: null
    }
  },
  created() {
    // 在组件创建时修正已有时间值的分钟部分
    this.normalizeTimeValues();
  },
  emits: ['update:startTime', 'update:endTime'],
  computed: {
    /**
     * 开始时间的计算属性，用于双向绑定
     * 确保时间值符合半小时规则
     */
    startTimeValue: {
      get() {
        return this.startTime;
      },
      set(value) {
        if (value) {
          // 确保分钟部分只能是0或30
          this.normalizeTimeValue(value);
        }
        this.$emit('update:startTime', value);
      }
    },
    /**
     * 结束时间的计算属性，用于双向绑定
     * 确保时间值符合半小时规则
     */
    endTimeValue: {
      get() {
        return this.endTime;
      },
      set(value) {
        if (value) {
          // 确保分钟部分只能是0或30
          this.normalizeTimeValue(value);
        }
        this.$emit('update:endTime', value);
      }
    }
  },
  methods: {
    /**
     * 限制分钟只能是0或30
     * @returns {Array} 被禁用的分钟值数组
     */
    disabledNonHalfHourMinutes() {
      const minutes = [];
      for (let i = 0; i < 60; i++) {
        if (i !== 0 && i !== 30) {
          minutes.push(i);
        }
      }
      return minutes;
    },
    
    /**
     * 为结束时间限制分钟，考虑开始时间的限制
     * @param {number} hour - 当前选择的小时
     * @returns {Array} 被禁用的分钟值数组
     */
    disabledEndTimeMinutes(hour) {
      const disabledList = this.disabledNonHalfHourMinutes();
      
      if (this.startTimeValue && hour === this.startTimeValue.getHours()) {
        const startMinutes = this.startTimeValue.getMinutes();
        for (let i = 0; i < 60; i++) {
          if (i < startMinutes && !disabledList.includes(i)) {
            disabledList.push(i);
          }
        }
      }
      
      return disabledList;
    },

    /**
     * 将时间值规范化为0或30分钟
     * @param {Date} time - 需要规范化的时间对象
     */
    normalizeTimeValue(time) {
      if (!time) return;
      
      const minutes = time.getMinutes();
      if (minutes !== 0 && minutes !== 30) {
        // 四舍五入到最近的半小时
        const roundedMinutes = Math.round(minutes / 30) * 30;
        time.setMinutes(roundedMinutes === 60 ? 0 : roundedMinutes);
        if (roundedMinutes === 60) {
          time.setHours(time.getHours() + 1);
        }
      }
    },
    
    /**
     * 规范化所有时间值
     * 在组件创建时调用，确保初始值符合半小时规则
     */
    normalizeTimeValues() {
      if (this.startTime) {
        this.normalizeTimeValue(this.startTime);
        this.$emit('update:startTime', new Date(this.startTime));
      }
      if (this.endTime) {
        this.normalizeTimeValue(this.endTime);
        this.$emit('update:endTime', new Date(this.endTime));
      }
    },
    
    /**
     * 处理开始时间变更
     * 当开始时间改变时，自动调整结束时间
     */
    handleStartTimeChange() {
      // 如果开始时间存在且结束时间为空或早于开始时间
      if (this.startTimeValue) {
        const startHours = this.startTimeValue.getHours();
        const startMinutes = this.startTimeValue.getMinutes();
        
        // 如果结束时间为空，设置默认结束时间为开始时间后1小时
        if (!this.endTimeValue) {
          const endTime = new Date(this.startTimeValue);
          endTime.setHours(endTime.getHours() + 1);
          this.$emit('update:endTime', endTime);
        } 
        // 如果结束时间早于开始时间，则调整结束时间
        else {
          const endHours = this.endTimeValue.getHours();
          const endMinutes = this.endTimeValue.getMinutes();
          
          if (endHours < startHours || (endHours === startHours && endMinutes < startMinutes)) {
            const endTime = new Date(this.startTimeValue);
            endTime.setHours(endTime.getHours() + 1);
            this.$emit('update:endTime', endTime);
          }
        }
      }
    },
    
    /**
     * 禁用早于开始时间的小时
     * @param {Date} startTime - 开始时间
     * @returns {Array} 被禁用的小时值数组
     */
    disabledHours(startTime) {
      if (!startTime) return [];
      
      const hours = startTime.getHours();
      const disabledHours = [];
      
      for (let i = 0; i < 24; i++) {
        if (i < hours) {
          disabledHours.push(i);
        }
      }
      return disabledHours;
    }
  }
}
</script>

<style scoped>
/* 时间范围选择器容器 */
.time-range-picker {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* 时间输入框样式 */
.time-input {
  width: 140px;
}

/* 时间分隔符样式 */
.time-separator {
  color: #606266;
  font-size: 14px;
}

/* 移动端适配 */
@media (max-width: 480px) {
  .time-range-picker {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  
  .time-separator {
    display: none;
  }
}
</style> 